// 自定义省略号
import { useState, useEffect, useRef, useMemo, useCallback } from 'react'

export default function Index() {
  /** 文字*/
  const textDom = useRef<HTMLDivElement | null>(null)
  const parentDom = useRef<HTMLDivElement | null>(null)
  /** 行高*/
  const rowHeight = useRef(0)
  const maxNum = 999999999;
  /** 行数*/
  const [row, setRow] = useState(maxNum)
  const [style, setStyle] = useState<React.CSSProperties>({});
  const [height, setHeight] = useState('100%')
  /** 字体高度*/
  const fontHeight = useRef(0)


  /** 获取应该省略几行*/
  const getWebkitLineClamp = useCallback((parentDom: HTMLElement, dom: HTMLElement) => {
    if (parentDom === null || dom === null) { 
      return maxNum
    }
    
    let parentInfo = parentDom.getBoundingClientRect()
    const range = document.createRange();
    range.setStart(dom, 0);
    range.setEnd(dom, dom.childNodes.length);
    let rangeHeight = range.getBoundingClientRect().height;
    let textContainerHeight = dom.getBoundingClientRect().height;

    setHeight(`100%`)
    //判断是否需要省略
    if (rangeHeight + (rowHeight.current - fontHeight.current) > textContainerHeight) {
      let rowNum = Math.floor(parentInfo.height / rowHeight.current)
      setHeight(`${rowNum * rowHeight.current}px`)
      return rowNum
    }
    return maxNum
  }, [])

  /** 获取实际row的高度*/
  const getRowHeight = useCallback((parentDom: HTMLElement, dom: HTMLElement) => {
    const styles = window.getComputedStyle(dom);
    let cssText = styles.cssText;
    if (!cssText) {
      cssText = Array.from(styles).reduce((str, property) => {
        return `${str}${property}:${styles.getPropertyValue(property)};`;
      }, '');
    }

    cssText += 'display:inline;opacity:0; '
    const textDom = document.createElement('div');
    textDom.innerHTML = 'as';
    textDom.style.cssText = cssText;
    (parentDom as any).appendChild(textDom);
    /** 获取样式*/
    let styleInfo = window.getComputedStyle(textDom);
    let textInfo = textDom.getBoundingClientRect();
    let lineHeight = styleInfo.lineHeight;
    let fontSize = styleInfo.fontSize;
    let resultLineHeight = 0;

    fontHeight.current = textInfo.height;

    /** 获取行高*/
    let regular = new RegExp('px')
    let regularOne = new RegExp('%')

    if (lineHeight === 'normal') {
      resultLineHeight = textInfo.height
    } else if (regular.test(lineHeight)) {
      resultLineHeight = Number(lineHeight.substring(0, lineHeight.length - 2))
    } else if (regularOne.test(lineHeight)) {
      resultLineHeight = Number(fontSize.substring(0, fontSize.length - 2)) * Number(lineHeight.substring(0, lineHeight.length - 1)) / 100
    } else {
      resultLineHeight = Number(lineHeight.substring(0, lineHeight.length - 2))
    }
    rowHeight.current = resultLineHeight;
    parentDom.removeChild(textDom);
    return resultLineHeight
  }, [])

  useEffect(() => {
    if (textDom.current === null || parentDom.current === null) {
      return
    }
    getRowHeight(parentDom.current, textDom.current)
    const resizeObserver = new ResizeObserver(entries => {
      setRow(getWebkitLineClamp(parentDom.current as HTMLDivElement, textDom.current as HTMLDivElement))
    });
    resizeObserver.observe(parentDom.current);
  }, [])

  useEffect(() => {
    setStyle({
      overflow: "hidden",
      textOverflow: "ellipsis",
      display: "-webkit-box",
      "WebkitLineClamp": row,
      "WebkitBoxOrient": "vertical",
      height: "100%",
      backgroundColor: "red",
      wordBreak: "break-all",
    })
  }, [row])


  return (
    <>
      <div style={{
        height: '50vh',
        minHeight: `${rowHeight.current}px`,
        width: '50vw',
        fontSize: "32px",
        lineHeight: "60px"
      }} ref={parentDom}>
        <div ref={textDom}
          style={{
            ...style,
            height: height,
          }}
        >
          蓦然回首，那每一个瞬间的感动都溢满了心扉，高悬的心墙上盛载着青涩与酸甜苦辣的果实，温和而善良的眼神使爱的节日变得更加温存而充盈。
        </div>
      </div>
    </>
  )
}